Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix MusicXML ties resolved to have an ending note coming before its starting note #3538

Merged
merged 2 commits into from
Oct 21, 2023

Conversation

paxbun
Copy link
Contributor

@paxbun paxbun commented Oct 20, 2023

This PR is to fix the MusicXML tie issue introduced by #3334.

The current code sets the onset of each tie's starting note to -1 when the tie is still open at the end of each measure.

verovio/src/iomusxml.cpp

Lines 1766 to 1769 in 545f379

else {
iter->m_note->SetScoreTimeOnset(-1); // make scoreTimeOnset small for next measure
++iter;
}

This is to make the onset comparison in MusicXmlInput::MatchTies returns true for notes in the adjacent measures.

verovio/src/iomusxml.cpp

Lines 1752 to 1759 in 545f379

if ((iter->m_note->IsEnharmonicWith(jter->m_note))
&& (iter->m_note->GetScoreTimeOnset() < jter->m_note->GetScoreTimeOnset())
&& (jter->m_note->GetScoreTimeOnset() < lastScoreTimeOnset)
&& (!matchLayers || (iter->m_layerNum == jter->m_layerNum))) {
iter->m_tie->SetEndid("#" + jter->m_note->GetID());
lastScoreTimeOnset = jter->m_note->GetScoreTimeOnset();
tieMatched = true;
break;

But #3334 runs this logic twice as follows, so for the second call to MatchTies, each open tie's starting note always has the onset -1, so the ties are resolved to have an ending note that comes before the starting note.

verovio/src/iomusxml.cpp

Lines 1709 to 1710 in 545f379

this->MatchTies(true);
if (!m_tieStack.empty()) this->MatchTies(false);

This PR moves that -1 logic right under the two calls to MusicXmlInput::MatchTies.

Here's an example that makes this problem.

Input data

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 4.0 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd">
<score-partwise version="4.0">
  <part-list>
    <score-part id="P1">
      <score-instrument id="P1-I1"/>
      <midi-device id="P1-I1" port="1"></midi-device>
      <midi-instrument id="P1-I1">
        <midi-channel>1</midi-channel>
        <midi-program>1</midi-program>
        <volume>100</volume>
        <pan>0</pan>
        </midi-instrument>
      </score-part>
    </part-list>
  <part id="P1">
    <measure number="1">
      <attributes>
        <divisions>4</divisions>
        <time>
          <beats>4</beats>
          <beat-type>4</beat-type>
          </time>
        <staves>1</staves>
        <clef number="1">
          <sign>G</sign>
          <line>2</line>
          </clef>
        </attributes>
      <note dynamics="66.67" id="M1C1">
        <pitch>
          <step>C</step>
          <octave>4</octave>
          </pitch>
        <duration>4</duration>
        <voice>1</voice>
        <type>quarter</type>
        <stem>up</stem>
        <staff>1</staff>
        </note>
      <note dynamics="66.67" id="M1G1">
        <chord/>
        <pitch>
          <step>G</step>
          <octave>4</octave>
          </pitch>
        <duration>4</duration>
        <voice>1</voice>
        <type>quarter</type>
        <stem>up</stem>
        <staff>1</staff>
        </note>
      <note dynamics="66.67" id="M1C2">
        <pitch>
          <step>C</step>
          <octave>4</octave>
          </pitch>
        <duration>4</duration>
        <voice>1</voice>
        <type>quarter</type>
        <stem>up</stem>
        <staff>1</staff>
        </note>
      <note dynamics="66.67" id="M1G2">
        <chord/>
        <pitch>
          <step>G</step>
          <octave>4</octave>
          </pitch>
        <duration>4</duration>
        <voice>1</voice>
        <type>quarter</type>
        <stem>up</stem>
        <staff>1</staff>
        </note>
      <note dynamics="66.67" id="M1C3">
        <pitch>
          <step>C</step>
          <octave>4</octave>
          </pitch>
        <duration>4</duration>
        <voice>1</voice>
        <type>quarter</type>
        <stem>up</stem>
        <staff>1</staff>
        </note>
      <note dynamics="66.67" id="M1G3">
        <chord/>
        <pitch>
          <step>G</step>
          <octave>4</octave>
          </pitch>
        <duration>4</duration>
        <voice>1</voice>
        <type>quarter</type>
        <stem>up</stem>
        <staff>1</staff>
        </note>
      <note dynamics="66.67" id="M1C4">
        <pitch>
          <step>C</step>
          <octave>4</octave>
          </pitch>
        <duration>4</duration>
        <tie type="start"/>
        <voice>1</voice>
        <type>quarter</type>
        <stem>up</stem>
        <staff>1</staff>
        <notations>
          <tied type="start" id="TC1"/>
          </notations>
        </note>
      <note dynamics="66.67" id="M1G4">
        <chord/>
        <pitch>
          <step>G</step>
          <octave>4</octave>
          </pitch>
        <duration>4</duration>
        <tie type="start"/>
        <voice>1</voice>
        <type>quarter</type>
        <stem>up</stem>
        <staff>1</staff>
        <notations>
          <tied type="start" id="TG1"/>
          </notations>
        </note>
      </measure>
    <measure number="2">
      <note dynamics="66.67" id="M2C1">
        <pitch>
          <step>C</step>
          <octave>4</octave>
          </pitch>
        <duration>4</duration>
        <tie type="stop"/>
        <voice>1</voice>
        <type>quarter</type>
        <stem>up</stem>
        <staff>1</staff>
        <notations>
          <tied type="stop"/>
          </notations>
        </note>
      <note dynamics="66.67" id="M2G1">
        <chord/>
        <pitch>
          <step>G</step>
          <octave>4</octave>
          </pitch>
        <duration>4</duration>
        <tie type="stop"/>
        <voice>1</voice>
        <type>quarter</type>
        <stem>up</stem>
        <staff>1</staff>
        <notations>
          <tied type="stop"/>
          </notations>
        </note>
      <note dynamics="66.67" id="M2C2">
        <pitch>
          <step>C</step>
          <octave>4</octave>
          </pitch>
        <duration>4</duration>
        <voice>1</voice>
        <type>quarter</type>
        <stem>up</stem>
        <staff>1</staff>
        <notations>
          <tied type="start" id="TC2"/>
          </notations>
        </note>
      <note dynamics="66.67" id="M2G2">
        <chord/>
        <pitch>
          <step>G</step>
          <octave>4</octave>
          </pitch>
        <duration>4</duration>
        <voice>1</voice>
        <type>quarter</type>
        <stem>up</stem>
        <staff>1</staff>
        <notations>
          <tied type="start" id="TG2"/>
          </notations>
        </note>
      <note dynamics="66.67" id="M2C3">
        <pitch>
          <step>C</step>
          <octave>4</octave>
          </pitch>
        <duration>4</duration>
        <voice>1</voice>
        <type>quarter</type>
        <stem>up</stem>
        <staff>1</staff>
        <notations>
          <tied type="stop"/>
          </notations>
        </note>
      <note dynamics="66.67" id="M2G3">
        <chord/>
        <pitch>
          <step>G</step>
          <octave>4</octave>
          </pitch>
        <duration>4</duration>
        <voice>1</voice>
        <type>quarter</type>
        <stem>up</stem>
        <staff>1</staff>
        <notations>
          <tied type="stop"/>
          </notations>
        </note>
      <note dynamics="66.67" id="M2C4">
        <pitch>
          <step>C</step>
          <octave>4</octave>
          </pitch>
        <duration>4</duration>
        <tie type="start"/>
        <voice>1</voice>
        <type>quarter</type>
        <stem>up</stem>
        <staff>1</staff>
        <notations>
          <tied type="start" id="TC3"/>
          </notations>
        </note>
      <note dynamics="66.67" id="M2G4">
        <chord/>
        <pitch>
          <step>G</step>
          <octave>4</octave>
          </pitch>
        <duration>4</duration>
        <tie type="start"/>
        <voice>1</voice>
        <type>quarter</type>
        <stem>up</stem>
        <staff>1</staff>
        <notations>
          <tied type="start" id="TG3"/>
          </notations>
        </note>
      </measure>
    <measure number="3">
      <note dynamics="66.67" id="M3C1">
        <pitch>
          <step>C</step>
          <octave>4</octave>
          </pitch>
        <duration>4</duration>
        <tie type="stop"/>
        <voice>1</voice>
        <type>quarter</type>
        <stem>up</stem>
        <staff>1</staff>
        <notations>
          <tied type="stop"/>
          </notations>
        </note>
      <note dynamics="66.67" id="M3G1">
        <chord/>
        <pitch>
          <step>G</step>
          <octave>4</octave>
          </pitch>
        <duration>4</duration>
        <tie type="stop"/>
        <voice>1</voice>
        <type>quarter</type>
        <stem>up</stem>
        <staff>1</staff>
        <notations>
          <tied type="stop"/>
          </notations>
        </note>
      <note dynamics="66.67" id="M3C2">
        <pitch>
          <step>C</step>
          <octave>4</octave>
          </pitch>
        <duration>4</duration>
        <voice>1</voice>
        <type>quarter</type>
        <stem>up</stem>
        <staff>1</staff>
        </note>
      <note dynamics="66.67" id="M3G2">
        <chord/>
        <pitch>
          <step>G</step>
          <octave>4</octave>
          </pitch>
        <duration>4</duration>
        <voice>1</voice>
        <type>quarter</type>
        <stem>up</stem>
        <staff>1</staff>
        </note>
      <note dynamics="66.67" id="M3C3">
        <pitch>
          <step>C</step>
          <octave>4</octave>
          </pitch>
        <duration>4</duration>
        <voice>1</voice>
        <type>quarter</type>
        <stem>up</stem>
        <staff>1</staff>
        </note>
      <note dynamics="66.67" id="M3G3">
        <chord/>
        <pitch>
          <step>G</step>
          <octave>4</octave>
          </pitch>
        <duration>4</duration>
        <voice>1</voice>
        <type>quarter</type>
        <stem>up</stem>
        <staff>1</staff>
        </note>
      <note dynamics="66.67" id="M3C4">
        <pitch>
          <step>C</step>
          <octave>4</octave>
          </pitch>
        <duration>4</duration>
        <voice>1</voice>
        <type>quarter</type>
        <stem>up</stem>
        <staff>1</staff>
        </note>
      <note dynamics="66.67" id="M3G4">
        <chord/>
        <pitch>
          <step>G</step>
          <octave>4</octave>
          </pitch>
        <duration>4</duration>
        <voice>1</voice>
        <type>quarter</type>
        <stem>up</stem>
        <staff>1</staff>
        </note>
      </measure>
    </part>
  </score-partwise>

Actual behavior after the fix

Render result:
image

All six ties must be rendered correctly.

Actual behavior before the fix

Render result:
image

Tie #TC3 is not rendered correctly.

MEI:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="https://music-encoding.org/schema/dev/mei-all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<?xml-model href="https://music-encoding.org/schema/dev/mei-all.rng" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
<mei xmlns="http://www.music-encoding.org/ns/mei" meiversion="5.0.0-dev">
   <meiHead xml:id="mfw54q1">
      <fileDesc xml:id="f17n6w76">
         <titleStmt xml:id="t1778bsb">
            <title />
            <respStmt />
         </titleStmt>
         <pubStmt xml:id="p19jo4i8" />
      </fileDesc>
      <encodingDesc xml:id="ez3u08y">
         <appInfo xml:id="aojd8rh">
            <application xml:id="al39mzs" isodate="2023-10-20T14:06:08" version="3.16.0-dev-3accf44">
               <name xml:id="n1wqbzbe">Verovio</name>
               <p xml:id="p1t4are0">Transcoded from MusicXML</p>
            </application>
         </appInfo>
      </encodingDesc>
   </meiHead>
   <music>
      <body>
         <mdiv xml:id="m1kpuopg">
            <score xml:id="s68fgqj">
               <scoreDef xml:id="s1lxy20f">
                  <staffGrp xml:id="s1i0ih0g">
                     <staffDef xml:id="P1" n="1" lines="5" ppq="4">
                        <instrDef xml:id="iy8xyvc" midi.channel="0" midi.instrnum="0" midi.volume="100.00%" />
                        <clef xml:id="cvw3pn1" shape="G" line="2" />
                        <meterSig xml:id="m1e95azo" count="4" unit="4" />
                     </staffDef>
                  </staffGrp>
               </scoreDef>
               <section xml:id="swqcgm0">
                  <measure xml:id="mz2k6oh" n="1">
                     <staff xml:id="spz4x43" n="1">
                        <layer xml:id="l17hphoq" n="1">
                           <chord xml:id="c1w9mcw2" dur.ppq="4" dur="4" stem.dir="up">
                              <note xml:id="M1C1" oct="4" pname="c" vel="60" />
                              <note xml:id="M1G1" oct="4" pname="g" vel="60" />
                           </chord>
                           <chord xml:id="c13lgc2c" dur.ppq="4" dur="4" stem.dir="up">
                              <note xml:id="M1C2" oct="4" pname="c" vel="60" />
                              <note xml:id="M1G2" oct="4" pname="g" vel="60" />
                           </chord>
                           <chord xml:id="c1g7s2wj" dur.ppq="4" dur="4" stem.dir="up">
                              <note xml:id="M1C3" oct="4" pname="c" vel="60" />
                              <note xml:id="M1G3" oct="4" pname="g" vel="60" />
                           </chord>
                           <chord xml:id="c3b9waf" dur.ppq="4" dur="4" stem.dir="up">
                              <note xml:id="M1C4" oct="4" pname="c" vel="60" />
                              <note xml:id="M1G4" oct="4" pname="g" vel="60" />
                           </chord>
                        </layer>
                     </staff>
                     <tie xml:id="TC1" startid="#M1C4" endid="#M2C1" />
                     <tie xml:id="TG1" startid="#M1G4" endid="#M2G1" />
                  </measure>
                  <measure xml:id="m1ph7lm5" n="2">
                     <staff xml:id="s1hp6sj8" n="1">
                        <layer xml:id="lmivrq3" n="1">
                           <chord xml:id="c3gnswr" dur.ppq="4" dur="4" stem.dir="up">
                              <note xml:id="M2C1" oct="4" pname="c" vel="60" />
                              <note xml:id="M2G1" oct="4" pname="g" vel="60" />
                           </chord>
                           <chord xml:id="c1ehv9zv" dur.ppq="4" dur="4" stem.dir="up">
                              <note xml:id="M2C2" oct="4" pname="c" vel="60" />
                              <note xml:id="M2G2" oct="4" pname="g" vel="60" />
                           </chord>
                           <chord xml:id="ctxjzey" dur.ppq="4" dur="4" stem.dir="up">
                              <note xml:id="M2C3" oct="4" pname="c" vel="60" />
                              <note xml:id="M2G3" oct="4" pname="g" vel="60" />
                           </chord>
                           <chord xml:id="c1ihxzne" dur.ppq="4" dur="4" stem.dir="up">
                              <note xml:id="M2C4" oct="4" pname="c" vel="60" />
                              <note xml:id="M2G4" oct="4" pname="g" vel="60" />
                           </chord>
                        </layer>
                     </staff>
                     <tie xml:id="TC2" startid="#M2C2" endid="#M2C3" />
                     <tie xml:id="TG2" startid="#M2G2" endid="#M2G3" />
                     <tie xml:id="TC3" startid="#M2C4" endid="#M2C3" />
                     <tie xml:id="TG3" startid="#M2G4" endid="#M3G1" />
                  </measure>
                  <measure xml:id="mqlvb4r" n="3">
                     <staff xml:id="s1ukedv8" n="1">
                        <layer xml:id="ls8k7dx" n="1">
                           <chord xml:id="c5ty2ga" dur.ppq="4" dur="4" stem.dir="up">
                              <note xml:id="M3C1" oct="4" pname="c" vel="60" />
                              <note xml:id="M3G1" oct="4" pname="g" vel="60" />
                           </chord>
                           <chord xml:id="c1a5w0di" dur.ppq="4" dur="4" stem.dir="up">
                              <note xml:id="M3C2" oct="4" pname="c" vel="60" />
                              <note xml:id="M3G2" oct="4" pname="g" vel="60" />
                           </chord>
                           <chord xml:id="cnit9i5" dur.ppq="4" dur="4" stem.dir="up">
                              <note xml:id="M3C3" oct="4" pname="c" vel="60" />
                              <note xml:id="M3G3" oct="4" pname="g" vel="60" />
                           </chord>
                           <chord xml:id="c13s5b5" dur.ppq="4" dur="4" stem.dir="up">
                              <note xml:id="M3C4" oct="4" pname="c" vel="60" />
                              <note xml:id="M3G4" oct="4" pname="g" vel="60" />
                           </chord>
                        </layer>
                     </staff>
                  </measure>
               </section>
            </score>
         </mdiv>
      </body>
   </music>
</mei>

Log:

[Warning] Tie 'TC3' is ignored, since start 'M2C4' does not occur temporally before end 'M2C3'.

Copy link
Contributor

@rettinghaus rettinghaus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

@rettinghaus
Copy link
Contributor

The test suite build failed. Could you please rebase on the latest develop?

@lpugin lpugin merged commit 782c1fc into rism-digital:develop Oct 21, 2023
5 checks passed
@paxbun paxbun changed the title Fix MusicXML ties that resolved to have an ending note coming before its starting note Fix MusicXML ties that is resolved to have an ending note coming before its starting note Oct 21, 2023
@paxbun paxbun changed the title Fix MusicXML ties that is resolved to have an ending note coming before its starting note Fix MusicXML ties resolved to have an ending note coming before its starting note Oct 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants